package com.beyondsoft.mcms.web;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.springframework.roo.addon.web.mvc.controller.finder.RooWebFinder;
import org.springframework.roo.addon.web.mvc.controller.scaffold.RooWebScaffold;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.beyondsoft.mcms.common.CommonUtils;
import com.beyondsoft.mcms.common.Constants;
import com.beyondsoft.mcms.domain.Category;
import com.beyondsoft.mcms.domain.FeeAmount;
import com.beyondsoft.mcms.domain.Item;

@RequestMapping("/feeamounts")
@Controller
@RooWebScaffold(path = "feeamounts", formBackingObject = FeeAmount.class, create = false, delete = false)
@RooWebFinder
public class FeeAmountController {

    @RequestMapping(method = RequestMethod.PUT, produces = "text/html")
    public String update(@Valid FeeAmount feeAmount, BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest) {
        
    	FeeAmount old = FeeAmount.findFeeAmount(feeAmount.getId());
    	
    	if (bindingResult.hasErrors()) {
    		if (bindingResult.hasFieldErrors("payAmount")){
	            populateEditForm(uiModel, feeAmount);
	            return "feeamounts/update";
    		}
        }
    	
    	feeAmount.setBusinessType(old.getBusinessType());
    	feeAmount.setPositionType(old.getPositionType());
    	feeAmount.setUpdateBy(CommonUtils.getCurrentUsername());
        feeAmount.setUpdateDate(new Date());
        
        uiModel.asMap().clear();
        feeAmount.merge();
        return "redirect:/feeamounts/" + encodeUrlPathSegment(feeAmount.getId().toString(), httpServletRequest);
    }

    void populateEditForm(Model uiModel, FeeAmount feeAmount) {
        uiModel.addAttribute("feeAmount", feeAmount);
        addDateTimeFormatPatterns(uiModel);
        List<Item> businesstypes = Item.findItemsByCategoryAndIsValid(Category.findCategory(new Long(Constants.BUSINESS_TYPE)), true).getResultList();
        uiModel.addAttribute("businesstypes", businesstypes);
        List<Item> positiontypes = Item.findItemsByCategoryAndIsValid(Category.findCategory(new Long(Constants.POSITION_TYPE)), true).getResultList();
        uiModel.addAttribute("positiontypes", positiontypes);
        List<Item> periodtypes = Item.findItemsByCategoryAndIsValid(Category.findCategory(new Long(Constants.FEE_PERIOD_TYPE)), true).getResultList();
        uiModel.addAttribute("periodtypes", periodtypes);
    }

    @RequestMapping(params = { "find=ByBusinessTypeAndPositionType", "form" }, method = RequestMethod.GET)
    public String findFeeAmountsByBusinessTypeAndPositionTypeForm(Model uiModel) {
        checkNewFeeAmount();
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        request.getSession().setAttribute("positionType", null);
        request.getSession().setAttribute("businessType", null);
        return findFeeAmountsByBusinessTypeAndPositionType(null, null, uiModel);
    }

    @RequestMapping(params = "find=ByBusinessTypeAndPositionType", method = RequestMethod.GET)
    public String findFeeAmountsByBusinessTypeAndPositionType(@RequestParam(value = "positionType", required = false) Item positionType, @RequestParam(value = "businessType", required = false) Item businessType, Model uiModel) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String page = request.getParameter("page");
        String size = request.getParameter("size");
        int sizeNo = size == null ? 10 : Integer.valueOf(size);
        int pageNo = page == null ? 1 : Integer.valueOf(page);
        if (page != null && size != null) {
            positionType = (Item) request.getSession().getAttribute("positionType");
            businessType = (Item) request.getSession().getAttribute("businessType");
        } else {
            request.getSession().setAttribute("positionType", positionType);
            request.getSession().setAttribute("businessType", businessType);
        }
        uiModel.addAttribute("positionType", positionType);
        uiModel.addAttribute("businessType", businessType);
        return list(pageNo, sizeNo, uiModel);
    }

    @RequestMapping(produces = "text/html")
    public String list(@RequestParam(value = "page", required = false) Integer page, @RequestParam(value = "size", required = false) Integer size, Model uiModel) {
        List<Item> businesstypes = Item.findItemsByCategoryAndIsValid(Category.findCategory(new Long(Constants.BUSINESS_TYPE)), true).getResultList();
        uiModel.addAttribute("businesstypes", businesstypes);
        List<Item> positiontypes = Item.findItemsByCategoryAndIsValid(Category.findCategory(new Long(Constants.POSITION_TYPE)), true).getResultList();
        uiModel.addAttribute("positiontypes", positiontypes);
        Item positionType = (Item) uiModel.asMap().get("positionType");
        Item businessType = (Item) uiModel.asMap().get("businessType");
        int sizeNo = size == null ? 10 : size.intValue();
        final int firstResult = page == null ? 0 : (page.intValue() - 1) * sizeNo;
        float nrOfPages = 0.0f;
        List<FeeAmount> feeamounts = FeeAmount.findFeeAmountsByBusinessTypeAndPositionType(businessType, positionType).getResultList();
        int lastResult = (feeamounts.size() > (sizeNo + firstResult)) ? (sizeNo + firstResult) : feeamounts.size();
        nrOfPages = (float) feeamounts.size() / sizeNo;
        uiModel.addAttribute("maxPages", (int) ((nrOfPages > (int) nrOfPages || nrOfPages == 0.0) ? nrOfPages + 1 : nrOfPages));
        uiModel.addAttribute("feeamounts", feeamounts.subList(firstResult, lastResult));
        uiModel.addAttribute("find", "ByBusinessTypeAndPositionType");
        uiModel.addAttribute("selectQueryIds", (businessType == null ? "-1" : businessType.getId()) + "," + (positionType == null ? "-1" : positionType.getId()));
        addDateTimeFormatPatterns(uiModel);
        return "feeamounts/list";
    }

    private static void checkNewFeeAmount() {
        List<Item> businesstypes = Item.findItemsByCategoryAndIsValid(Category.findCategory(new Long(Constants.BUSINESS_TYPE)), true).getResultList();
        List<Item> positiontypes = Item.findItemsByCategoryAndIsValid(Category.findCategory(new Long(Constants.POSITION_TYPE)), true).getResultList();
        List<FeeAmount> feeAmounts = FeeAmount.findAllFeeAmounts();
        for (int i = 0; i < businesstypes.size(); i++) {
            Item businessType = businesstypes.get(i);
            for (int j = 0; j < positiontypes.size(); j++) {
                Item positionType = positiontypes.get(j);
                if (!feeAmountIsExists(businessType, positionType, feeAmounts)) {
                    FeeAmount feeAmount = new FeeAmount();
                    feeAmount.setBusinessType(businessType);
                    feeAmount.setPositionType(positionType);
                    feeAmount.setPayAmount(new BigDecimal(0.0));
                    feeAmount.setFeePeriod(Item.findItem(Constants.FEE_PERIOD_YEAR));
                    feeAmount.setUpdateBy(CommonUtils.getCurrentUsername());
                    feeAmount.setUpdateDate(new Date());
                    feeAmount.persist();
                }
            }
        }
    }

    private static boolean feeAmountIsExists(Item businessType, Item positionType, List<FeeAmount> feeAmounts) {
        for (Iterator<FeeAmount> it = feeAmounts.iterator(); it.hasNext(); ) {
            FeeAmount feeAmount = it.next();
            if (feeAmount.getBusinessType().getId().equals(businessType.getId()) 
            		&& feeAmount.getPositionType().getId().equals(positionType.getId())) {
                return true;
            }
        }
        return false;
    }
}
